#pragma once

// Vector2_t
// (Thomas Rippon) Represents a 2-dimensional euclidean vector
template<class T>
class Vector2_t {
public: // Typedefs
	typedef T value_type;
	typedef Vector2_t<T> this_type;

public: // Constructors
	Vector2_t();
	Vector2_t( T x, T y );

	// Conversion to other type of vector (no implicit conversion)
	template<class U>
	explicit Vector2_t( const Vector2_t<U>& vec ) : x(vec.x), y(vec.y) { }

public: // Named constructors
	static this_type fromAngle( T angle, T length ); // Doesn't make sense for integral types

public: // Operators
	const this_type operator - () const;
	const this_type operator + ( const this_type& vec ) const;
	const this_type operator - ( const this_type& vec ) const;
	const this_type operator * ( const this_type& vec ) const;
	const this_type operator / ( const this_type& vec ) const;
	const this_type operator * ( T scalar ) const;
	const this_type operator / ( T scalar ) const;

	this_type& operator += ( const this_type& vec );
	this_type& operator -= ( const this_type& vec );
	this_type& operator *= ( const this_type& vec );
	this_type& operator /= ( const this_type& vec );
	this_type& operator *= ( T scalar );
	this_type& operator /= ( T scalar );

public: // Comparison Operators
	bool operator == ( const this_type& vec ) const;
	bool operator != ( const this_type& vec ) const;
	bool operator < ( const this_type& vec ) const;

public: // Methods
	T dot( const this_type& vec ) const;
	T sqLength() const;
	T length() const;
	this_type& normalize();
	const this_type normalized() const;
	const this_type rhNormal() const;
	const this_type lhNormal() const;
	const this_type projectionOnto( const this_type& vec ) const;
	const T projectionLength( const this_type& vec ) const;
	const this_type reflected( const this_type& normal ) const;
	const T angle( const this_type& vec ) const; // Doesn't make sense for integral types

public: // Members
	T x, y;
};

typedef Vector2_t<int> Vector2i;
typedef Vector2_t<double> Vector2;